程式設計是可以玩一輩子的東西,你認為呢?
在上一篇我們已經把基本的產品列表渲染出來頁面了,並且可以新增或刪除產品,我們可以發現在新增產品時,出現的時間規格並不是我們要的,這部分我們會留到後續再處理。
我們希望可以利用關鍵字keywords
來搜尋產品,在使用者輸入搜尋的 input 文字框時,按下 enter 就會把所有包含有關鍵字的產品渲染到頁面來。在還沒增加搜尋功能之前,我們的列表來源是以v-for
來渲染 lists
所得到的所有內容,但如果要增加搜尋功能,列表會依搜尋的結果而渲染列表,所以遍歷的目標則是以我們為搜尋寫的方法search(keywords)
加上搜尋關鍵字為參數,透過傳參數的方式,傳給search()
方法。
在這之前,可以先了解一下以下五個 JavaScript 內建方法forEach(), some(), filter(), findIndex()
的差異,這四個方法都可以對陣列中的每一各元素進行遍歷,執行相關的操作,達到以關鍵字過濾的效果。
方法 | 作用 |
---|---|
Array.prototype.forEach() | 遍歷時無法終止。 |
Array.prototype.some() | 透過回傳 true 讓它終止。 |
Array.prototype.filter() | 過濾用,檢查陣列裡面的值是否符合條件,把符合條件的存入成為一個新陣列。 |
Array.prototype.findIndex() | 依據提供的測試函式,尋找陣列中符合的元素,並返回其 index(索引)。如果沒有符合的對象,將返回 -1 。 |
String.prototype.includes() | string.prototype('要包含的字串'),有包含會回傳 true 否則 false。用於判斷一個字符串是否包含在另一個字符串中,根據情況返回 true 或 false。includes() 方法是區分大小寫的。 |
第一個forEach()
是我們常用的,但是無論有無搜尋到我們要的關鍵字,forEach()
都會把陣列從頭到尾遍歷一遍。
在以關鍵字keywords
搜尋的search()
方法裡,透過迴圈遍歷,把符合搜尋關鍵字的資料保存到另一個搜尋結果的列表,再以這個新列表渲染頁面。
來看一下Codepen 的範例
HTML 的部分
先把搜尋的輸入框寫好,並以v-on
綁定監聽事件,使用修飾符.enter
,在輸入搜尋內容按下 enter 鍵時去呼叫search
方法,同時以v-model
雙向綁定,並在Date
裡初始化資料為空字串''
。
<div id="app">
<h3>增加商品</h3>
<div>
ID:<input type="text" v-model="id" /> | Name:<input
type="text"
v-model="name"
/><input type="button" value="Add" @click="addItem" /> | Search:<input
type="text"
v-model="keywords"
@keyup.enter="search"
/>
</div>
<table>
<thead>
<tr>
<td>Id</td>
<td>Name</td>
<td>Time & Date</td>
<td>Operation</td>
</tr>
</thead>
<tbody>
<!-- <tr v-for="item in lists" :key="item.id"> -->
<!-- 以搜尋結果渲染頁面 -->
<tr v-for="item in search(keywords)" :key="item.id">
<td>{{ item.id }}</td>
<td v-text="item.name"></td>
<td>{{ item.timeDate}}</td>
<td><a href="" @click.prevent="deleteItem(item.id)">Delete</a></td>
</tr>
</tbody>
</table>
</div>
當搜尋時沒有給字符串也就等於空的字符串''
但為什麼空字符串卻會顯示所有的列表內容?因為我們使用indexOf()
時,如果給''
會回傳 0,indexOf()
回傳-1 表示沒找到,也就是說''
空字符串是包含在有找到目標之內的,也因此可以顯示所有內容。
JavaScript 的部分
const vm = new Vue({
el: '#app',
data: {
id: '',
name: '',
keywords: '',
lists: [
{
id: 1,
name: 'Vue',
timeData: new Date(),
},
{
id: 2,
name: 'React',
timeData: new Date(),
},
{
id: 3,
name: 'JavaScript',
timeData: new Date(),
},
],
},
methods: {
addItem: function () {
var item = { id: this.id, name: this.name, timeDate: new Date() };
console.log(item);
this.lists.push(item);
this.id = '';
this.name = '';
// this.id=this.name=''
},
deleteItem: function (id) {
// 使用some()來循環,找到會回傳true並立即中止
// 用迴圈去找index
this.lists.some((item, i) => {
if (item.id == id) {
this.lists.splice(i, 1);
return true;
}
});
// 另一種抓index的方式
// let index = this.lists.findIndex((item) => {
// if (item.id == id) return true;
// });
// console.log(index);
// this.splice(index. 1)
},
// 搜尋方法
search: function (keywords) {
// 第一種寫法:將搜尋結果存在searchLists ,遍歷完之後再回傳新資料列表
// let searchLists = [];
// this.lists.forEach((item) => {
// if (item.name.indexOf(keywords) != -1) {
// searchLists.push(item);
// }
// return searchLists;
// });
// 第一種寫法:直接將結果回傳
return this.lists.filter((item) => {
// if(item.name.indexOF(keywords != -1))
if (item.name.includes(keywords)) {
return item;
}
});
},
},
});
利用 JavaScript 不同的方法特性,可以很簡潔地寫出搜尋的功能,是不是很方便!
每日一句法文有益身心:Il fait froid ! --> 以.飛.發! --> 好冷喔!是冷的。